#include <iostream>
#include "my_malloc.hpp"
#define MEM_SIZE 128*4096
template<class T>
class ObjectPool
{
    private:
        void*& NextPtr(void* node)
        {
            return (*(void**)node);
        }
    public:
    ObjectPool() : _memory(nullptr) , _remainBytes(0) , _freeList(nullptr)
    {}
    T* New()
    {
        //1.查看自由链表中是否有节点可用
        T* obj = nullptr;
        if(_freeList != nullptr)
        {
            //自由链表中有节点
            obj = (T*)_freeList;
            _freeList = NextPtr(_freeList);
        }
        else 
        {
            //自由链表中无节点
            //判断申请内存大小，一个对象中至少要能存储指针
            size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
            if(_remainBytes < objSize)
            {
                //剩余大小，小于需要的大小
                _remainBytes = MEM_SIZE;
                _memory = (char*)my_malloc(_remainBytes);
                if(_memory == nullptr)
                {
                    throw std::bad_alloc();
                }
            }
            //从大块内存中切出objsize字节大小的内存块
            obj = (T*)_memory;
            _memory += objSize;
            _remainBytes -= objSize;
        }
        //定位new
        new(obj)T;
        return obj;
    }
    void Delete(T* obj)
    {
        //显式调用T的析构函数清理对象
        obj->~T();
        //将释放的对插头插至自由链表中
        NextPtr(obj) = _freeList;
        _freeList = obj;
    }
    private:
        char* _memory; //指向大块内存的指针
        size_t _remainBytes; //大块内存在切分过程中剩余字节
        void* _freeList; //还回来过程中链接的自由链表的头指针
};